package picounit.java.collection;

import java.util.Arrays;
import java.util.LinkedList;

public class List<T> extends Iterable<T> {
    public static <T> List<T> create(Iterable<T> iterable) {
        java.util.List<T> list = new LinkedList<T>();

        for (T item : iterable) {
            list.add(item);
        }

        return new List<T>(list);
    }

    public static <T> List<T> create(T ... array) {
        return new List<T>(array);
    }

    public List(T ... array) {
        this(new LinkedList<T>(Arrays.asList(array)));
    }

    public List() {
        this(new LinkedList<T>());
    }

    public void add(T item) {
        list.add(item);
    }

    public void remove(T item) {
        list.remove(item);
    }

    public void addAll(List<T> toAdd) {
        toAdd.addTo(this);
    }

    public void addTo(List<T> list) {
        for (T item : this) {
            list.add(item);
        }
    }

    public boolean equalTo(List<T> list) {
        return list.size() == size() &&
            containsAll(list);
    }

    public boolean containsAll(List<T> list) {
        if (size() < list.size()) {
            return false;
        }

        for (T item : list) {
            if (!this.list.contains(item)) {
                return false;
            }
        }

        return true;
    }

    public int size() {
        return list.size();
    }

    @Override
    @SuppressWarnings("unchecked")
    public boolean equals(Object object) {
        if (object == null || !getClass().equals(object.getClass())) {
            return false;
        }

        List<T> other = (List<T>) object;

        return other.size() == size() &&
            containsAll(other);
    }

    @Override
    public String toString() {
        return list.toString();
    }

    private List(java.util.List<T> list) {
        super(list);

        this.list = list;
    }

    private final java.util.List<T> list;
}